package com.df.ez_game.server.doc;


import com.alibaba.fastjson2.JSON;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@ChannelHandler.Sharable
// 自定义请求处理器
public class DocServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    private static final Map<String, String> MIME_TYPES = Map.of(
            ".html", "text/html",
            ".js", "application/javascript",
            ".css", "text/css",
            ".json", "application/json"
    );

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
        String uri = request.uri();
        HttpMethod method = request.method();

        try {
            // 处理根路径请求，返回 index.html
            if ("/".equals(uri) && HttpMethod.GET.equals(method)) {
                serveStaticFile(ctx, "doc/index.html", request);
                return;
            }

            // 处理 API 元数据请求
            if ("/api_metadatas".equals(uri) && HttpMethod.GET.equals(method)) {
                handleApiMetadatas(ctx, request);
                return;
            }

            // 处理前端代码生成请求
            if (uri.startsWith("/generator/front/") && HttpMethod.GET.equals(method)) {
                handleFrontendCodeGeneration(ctx, uri, request);
                return;
            }

            // 处理后端 RPC 接口代码生成请求
            if (uri.startsWith("/generator/rpc/") && HttpMethod.GET.equals(method)) {
                handleRpcCodeGeneration(ctx, uri, request);
                return;
            }

            // 处理静态文件请求
            if (HttpMethod.GET.equals(method) && uri.startsWith("/")) {
                serveStaticFile(ctx, uri.substring(1), request);
                return;
            }

            // 404 处理
            sendError(ctx, HttpResponseStatus.NOT_FOUND, "Resource not found: " + uri);

        } catch (Exception e) {
            sendError(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR, "Internal server error: " + e.getMessage());
        }
    }

    private void serveStaticFile(ChannelHandlerContext ctx, String filePath, FullHttpRequest request) {
        try {
            // 安全检查，防止路径遍历攻击
            if (filePath.contains("..")) {
                sendError(ctx, HttpResponseStatus.FORBIDDEN, "Forbidden");
                return;
            }

            // 默认文件为 index.html
            if (filePath.isEmpty() || filePath.endsWith("/")) {
                filePath += "index.html";
            }

            // 从 resources 目录读取文件
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filePath);
            if (inputStream == null) {
                sendError(ctx, HttpResponseStatus.NOT_FOUND, "File not found: " + filePath);
                return;
            }

            byte[] content = inputStream.readAllBytes();
            inputStream.close();

            // 确定 Content-Type
            String contentType = "text/plain";
            for (Map.Entry<String, String> entry : MIME_TYPES.entrySet()) {
                if (filePath.endsWith(entry.getKey())) {
                    contentType = entry.getValue();
                    break;
                }
            }

            // 构建响应
            FullHttpResponse response = new DefaultFullHttpResponse(
                    HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK,
                    Unpooled.copiedBuffer(content)
            );

            response.headers().set(HttpHeaderNames.CONTENT_TYPE, contentType);
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.length);
            response.headers().set(HttpHeaderNames.CACHE_CONTROL, "no-cache");

            ctx.writeAndFlush(response);

        } catch (Exception e) {
            sendError(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error reading file: " + e.getMessage());
        }
    }

    private void handleApiMetadatas(ChannelHandlerContext ctx, FullHttpRequest request) {
        try {
            // 这里应该从您的系统中获取真实的元数据
            // 这里只是一个示例
            Map<String, Object> metadata = new HashMap<>();
            metadata.put("controllers", List.of("UserController", "OrderController"));
            metadata.put("version", "1.0.0");
            metadata.put("timestamp", System.currentTimeMillis());

            String jsonResponse = JSON.toJSONString(metadata);

            FullHttpResponse response = new DefaultFullHttpResponse(
                    HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK,
                    Unpooled.copiedBuffer(jsonResponse, StandardCharsets.UTF_8)
            );

            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, jsonResponse.length());

            ctx.writeAndFlush(response);

        } catch (Exception e) {
            sendError(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error generating metadata: " + e.getMessage());
        }
    }

    private void handleFrontendCodeGeneration(ChannelHandlerContext ctx, String uri, FullHttpRequest request) {
        try {
            // 解析路径参数：/generator/front/{platform}/{controllerName}/{codec}
            String[] pathSegments = uri.split("/");
            if (pathSegments.length < 6) {
                sendError(ctx, HttpResponseStatus.BAD_REQUEST, "Invalid path format");
                return;
            }

            String platform = pathSegments[3]; // ts, c#, etc.
            String controllerName = pathSegments[4];
            String codec = pathSegments[5]; // json, protobuf, etc.

            // 这里应该调用实际的代码生成逻辑
            String generatedCode = generateFrontendCode(platform, controllerName, codec);

            // 设置合适的 Content-Type 和文件名
            String contentType = getContentTypeForPlatform(platform);
            String filename = controllerName + getFileExtension(platform);

            FullHttpResponse response = new DefaultFullHttpResponse(
                    HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK,
                    Unpooled.copiedBuffer(generatedCode, StandardCharsets.UTF_8)
            );

            response.headers().set(HttpHeaderNames.CONTENT_TYPE, contentType);
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, generatedCode.length());
            response.headers().set(HttpHeaderNames.CONTENT_DISPOSITION,
                    "attachment; filename=\"" + filename + "\"");

            ctx.writeAndFlush(response);

        } catch (Exception e) {
            sendError(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error generating frontend code: " + e.getMessage());
        }
    }

    private void handleRpcCodeGeneration(ChannelHandlerContext ctx, String uri, FullHttpRequest request) {
        try {
            // 解析路径参数：/generator/rpc/{controllerName}
            String[] pathSegments = uri.split("/");
            if (pathSegments.length < 4) {
                sendError(ctx, HttpResponseStatus.BAD_REQUEST, "Invalid path format");
                return;
            }

            String controllerName = pathSegments[3];

            // 这里应该调用实际的 RPC 代码生成逻辑
            String generatedCode = generateRpcCode(controllerName);

            FullHttpResponse response = new DefaultFullHttpResponse(
                    HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK,
                    Unpooled.copiedBuffer(generatedCode, StandardCharsets.UTF_8)
            );

            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, generatedCode.length());
            response.headers().set(HttpHeaderNames.CONTENT_DISPOSITION,
                    "attachment; filename=\"" + controllerName + "Rpc.java\"");

            ctx.writeAndFlush(response);

        } catch (Exception e) {
            sendError(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error generating RPC code: " + e.getMessage());
        }
    }

    private String generateFrontendCode(String platform, String controllerName, String codec) {
        // 这里实现实际的前端代码生成逻辑
        // 示例实现
        return String.format("// Generated %s frontend code for %s with %s codec\n",
                platform, controllerName, codec);
    }

    private String generateRpcCode(String controllerName) {
        // 这里实现实际的 RPC 代码生成逻辑
        // 示例实现
        return String.format("// Generated RPC interface for %s\n", controllerName);
    }

    private String getContentTypeForPlatform(String platform) {
        switch (platform.toLowerCase()) {
            case "ts": return "application/typescript";
            case "c#": return "text/plain";
            default: return "text/plain";
        }
    }

    private String getFileExtension(String platform) {
        switch (platform.toLowerCase()) {
            case "ts": return ".ts";
            case "c#": return ".cs";
            default: return ".txt";
        }
    }

    private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status, String message) {
        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1,
                status,
                Unpooled.copiedBuffer(message, StandardCharsets.UTF_8)
        );
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, message.length());

        ctx.writeAndFlush(response);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}